<?php

namespace paymch\models;

use Yii;
use yii\db\Exception;
use common\models\trade\TradeOrder;
use common\models\original\UserAccount;
use common\models\original\UserAccountLogs;
use common\helpers\Utils;

/**
 * 退款交易
 * AlipayForm is the model behind the alipay async notify form.
 * 
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
class RefundHandler extends BasePaymentModel {

    public static function trade($id, &$msg) {
        $model = TradeOrder::findOne($id);
        if ($model == null || $model->trade == null) {
            $msg = '未找到订单信息！';
            return false;
        }
        if ($model->balance != TradeOrder::BALANCE_REFUND || $model->status != TradeOrder::STATUS_DEFAULT) {
            $msg = '交易状态无效！';
            return false;
        }

        $originalTrade = $model->paymentTrade;
        if (!$originalTrade) {
            $msg = '原始交易不存在！';
            return false;
        }

        parent::invokeLog('[' . $id . ']RefundHandler', $model->attributes);

        $request = [
            "out_trade_no" => $model->original_no,
            "amount" => $originalTrade->cash,
            "refund" => $model->pay,
            "reason" => $originalTrade->body,
            "refund_no" => $model->trade->trade_no,
        ];

        parent::invokeLog('[' . $id . ']Request Data', $request);

        $paymode = $model->paymode;

        //return $request;
        return static::$paymode($request);
    }

    /**
     * alipay
     * @return mixed
     */
    public static function alipay($params) {
        $aop = new \paymch\components\alipay\aop\AopClient();
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->appId = Yii::$app->params['alipay']['appid'];
        $aop->rsaPrivateKey = 'MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD0O4X7hUgrmT7J+4rCV1Rb/86l+dNIzua4HRQbZm+pwDEmgoKEwz6UUp2TMR1tKZuxQtDZqZH495SoqsAkar8vOMri4MrFS0lmHH6iyYIMIGSzPZEqMJRffzCutXoCJUWD++fYUyn2cRn+esic1+/Fh6uzo1B5nznF6ThQ75ubzX+S0p8WnHUeBlBwQ+nOe4krjVDu2a1aoCc9c8YgTKZtDlAqlSljqbG3kPZNEASoxov2Wzh7xYpuQNDXgOAmnwNDoWkdqiNI+SWOc05tBJi5WVnGtqPkzbdQKsP13lkw4Eu9W+D14RdFVjdD2jmM+9z+b0BsI0aZ0+7AcKyt2x43AgMBAAECggEAEQEv8/I0syxpTcDgyWUxL3KhHbdGObSGJd2Ib9vy/FuwUGEX20yIx+T0qbHqvZX/DBl91xnSWwZJ6HBzDlYMV6pZnfBOzevPAXgMbSMgld2PhVdNCyX0vq1pY1CpXQrhSy431zz7F/iJ+cjsvNbgD93BW7GMQduPNzNkw2XbbL6ASJuiresgdkGZIZtLoSKaIzojGJELBeSPWME1ODWdxkxd05og6U3I/FQH0ElTIVZ4j0BptWJsfKGtT4gn6gZ+cfpdtI+jKWtCZcg8g4OCRFtcMDRAUAsEdCsLo+Mw7O9uITySnctptXeffhGMmbCVKIIX16qy/8xexdfjjUS0WQKBgQD6QMRDpAMjRIqlQY5yNIQQIJlHEGAQ+S4d6vur/N747do0ucUolNZprHtLUmmtfVb5jgPXbIrr4ueuS8YhbTBIuHN+dSQ/WHAJoRLDx7wGI3VTvUc6onfYL+uuA8jYadO5s4ITcVuB0GJWdGOA7HgmAUlOJkYIm5OIVgP5EjECdQKBgQD511zGEbgZY1Nrt8095ybryK4A2l8nLyTheJafsoBcbqUmC8XR0zfqLQa8hY3bJNaHCL4bVZNFHMJVBvZp/3ubJ8ZPtGXQlKut2ZfXzUiydbVQn25fT/M2v8bPiiI/vx5aAoSXBUcObC6Qiy77xPiy8b7AooRH5UPKUu+uU1UwewKBgQC88XN9gnKgCRsJBIMRNRdUudggcHuntQsdqZIU25pZpfOvBWeXaTCtnn2EdBe31j95scCywI/u42V7EljoWfEvppwEqVsRvKryijuJt979X34xGGKUIaCMiDnQK6lTxCsINUELfvXRAE2O6tdJusBIKYZ4S6tqylPMhuz++74nFQKBgQDSNZ6sVFpGmiilODeqvuMjfWzR8OogiO0J/DEXWtPfcYTolv0xRvsDwDCry98IJF2Prg5t5zmK6+CiM8J+euQgLn4Pr+P+dChilPLKMsHYzWrp08rEzPsA9KitFDcu1XoPF5FBk8IuY11mZoT4dskdnoL1h4evCjpYcCGT1i+WIwKBgQDroCMSy28ElypZQvp8ZagSqJHGy5i/KdklRmbfWT99IEtx8G9E/ptUpM98bECXIStpu+w1qhM/CMkvdBeW+E5PtVYIZmod8Xdy11XBiS2zIBjJHmZXR6Y1INjK02Yn69xu8WlD3o0PX9I7OrZw97MwXBuEMSSqOdmQ3ZUwWjWgpQ==';
        $aop->alipayrsaPublicKey = Yii::$app->params['alipay']['public'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';

        $request = new \paymch\components\alipay\aop\request\AlipayTradeRefundRequest();
        $data = [
            "out_trade_no" => $params['out_trade_no'],
            "refund_amount" => $params['refund'],
            "refund_reason" => $params['reason'],
            "out_request_no" => $params['refund_no'],
        ];

        parent::invokeLog('Alipay Request', $data);

        $jsonstring = \yii\helpers\Json::encode($data);
        $request->setBizContent($jsonstring);

        $result = $aop->execute($request);
        parent::invokeLog('Alipay Response', $result);
        return $result;
    }

    /**
     * wechat
     * @return mixed
     */
    public static function wechat($params) {
        //操作退款请求
        $request = [
            'out_trade_no' => $params['out_trade_no'],
            'out_refund_no' => $params['refund_no'],
            'total_fee' => $params['amount'] * 100,
            'refund_fee' => $params['refund'] * 100,
            'refund_desc' => $params['reason'],
        ];
        parent::invokeLog('Wechat Request', $request);

        $result = Yii::$app->wxpay->refund($request);

        parent::invokeLog('Wechat Response', $result);
        return $result;
    }

    /**
     * credit
     * @return mixed
     */
    public static function credit($model, &$msg) {
        //判断是否已退
        if ($model->status == TradeOrder::STATUS_SUCCESS || $model->pay_no || $model->pay_time) {
            $msg = '积分退款支付状态已变更';
            return false;
        }
        $trade = $model->trade;

        $paymentCredit = $trade->credit;
        $tradeCredit = TradeOrder::find()
        ->where([
            'original_no' => $model->original_no,
            'paymode' => TradeOrder::PAYMODE_CREDIT
        ])
        ->sum('pay*balance*status');

        if (bccomp($model->pay, $tradeCredit, 2) > 0) {
            //剩余可退或者剩余积分不足以退掉当前的退款申请
            $msg = '支付积分不足以退';
            return false;
        }

        //退积分 开启事务
        $transaction = Yii::$app->db->beginTransaction();
        try {
            //退回用户积分账户
            $account = UserAccount::findOne(['user_id' => $trade->user_id]);
            $account->credit += $model->pay * 10;
            $account->updated_at = date('Y-m-d H:i:s');
            if (!$account->save()) {
                throw new Exception('账户积分退还失败！' . Utils::arrayToString($account->errors, true));
            }
            //创建积分日志
            $creditLog = new UserAccountLogs();
            $creditLog->attributes = [
                'user_id' => $trade->user_id,
                'type' => 'credit',
                'amount' => $model->pay * 10,
                'current' => $account->credit,
                'ip' => Yii::$app->request->userIP,
                'mark' => '【系统】积分退款' . $trade->subject,
                'detail' => 'trade_order',
                'detail_id' => $model->id,
            ];
            if (!$creditLog->save()) {
                throw new Exception('退款交易积分支付单号保存失败！' . Utils::arrayToString($creditLog->errors, true));
            }
            //积分支付
            $model->pay_no = strval($creditLog->id);
            $model->pay_time = $creditLog->input_at;
            $model->status = TradeOrder::STATUS_SUCCESS;
            if (!$model->save()) {
                throw new Exception('退款交易积分支付单号保存失败！' . Utils::arrayToString($model->errors, true));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $msg = $e->getMessage();
            return false;
        }
        return true;
    }

}
